package com.ng.security.exterauth.interceptor;


import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import com.ng.common.exception.NgException;
import com.ng.common.utils.HttpContextUtils;
import com.ng.exterauth.entity.SysExterAppEntity;
import com.ng.exterauth.entity.SysExterAppTokenEntity;
import com.ng.exterauth.service.SysExterAppService;
import com.ng.exterauth.service.SysExterAppTokenService;
import com.ng.exterauth.service.SysExterPermsService;
import com.ng.security.exterauth.annotation.AppPerm;
import com.ng.security.exterauth.annotation.NoLogin; 

/**
 * 权限(Token)验证
 * @author lyf
 * @email liuyf@gs-softwares.com
 * @date 2017-03-23 15:38
 */
@Component
public class AuthorizationInterceptor implements AsyncHandlerInterceptor {
  

    public static final String APP_KEY = "appId";
    
    public static final String TOKEN_HEADER = "tr-app-token";
    
    @Autowired
    private  SysExterAppService exterAppService ;
    
    @Autowired
    private  SysExterAppTokenService exterAppTokenService ;
    
    @Autowired
    private SysExterPermsService exterPermService;
     

    /**
     * 2020-04-17 修改 注解了 NoLogin的方法将不严重是否登录
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        NoLogin annotation;
        AppPerm aperm; 
        if(handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(NoLogin.class);
            aperm = ((HandlerMethod) handler).getMethodAnnotation(AppPerm.class); 
        }else{
            return true;
        }

        if(annotation != null){
            return true;
        }

        //获取用户凭证
        
        String token = HttpContextUtils.getRequestToken(request,TOKEN_HEADER);
     

        //凭证为空
        if(StringUtils.isBlank(token)){
            //throw new RRException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
            throw new NgException("请先登录", HttpStatus.UNAUTHORIZED.value());
        }
         
     /*   Claims claims = jwtUtils.getClaimByToken(token);
        if(claims == null){
            throw new RRException(jwtUtils.getHeader() + "失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }*/
        
        // user 存在说明还在有效期并且用户存在
        SysExterAppTokenEntity appToken = exterAppTokenService.queryByToken(token);
        
		if(appToken == null  ) {
			throw new NgException("请先登录", HttpStatus.UNAUTHORIZED.value());
		}
		
		SysExterAppEntity app = exterAppService.getById(appToken.getAppId());
		if(app == null  ) {
			throw new NgException("请先登录", HttpStatus.UNAUTHORIZED.value());
		}
		if(app.getStatus() == 0) {
			throw new NgException("当前账号已被禁用", HttpStatus.UNAUTHORIZED.value());
		}
 		
		request.setAttribute("app", app);
        
        //判断权限perm
        if(aperm != null){
        	
        	String perm = aperm.value();
        	 
        	
        	// 判断此处基于角色还是基于具体的权限码
        	if(perm != null && !perm.trim().isEmpty()) {
        		Set<String> perms = exterPermService.queryByApp(app.getId());
        		if(perms == null || !perms.contains(perm)) {
            		throw new NgException("操作失败，您当前无此权限!", HttpStatus.UNAUTHORIZED.value());
            	}
        	}
        	 
        } 

        //设置userId到request里，后续根据userId，获取用户信息
        request.setAttribute(APP_KEY, app.getId());

        return true;
    }
}
